/*-*-C-*-
 *
 * Sorting code
 */

#include "resed.h"


/*
 * Ordering function for icons.
 */

static int compare_icon (const void *a, const void *b)
{
    RectPtr ap = &((IconInfoPtr)a)->icon.bbox;
    RectPtr bp = &((IconInfoPtr)b)->icon.bbox;

    if (ap->miny > bp->maxy)
        return -1;
    else if (ap->maxy < bp->miny)
        return 1;
    else if (ap->maxx < bp->minx)
        return -1;
    else if (ap->minx > bp->maxx)
        return 1;
    else
        return 0;
}


/*
 * Ordering function for ints
 */

static int compare_int (const void *a, const void *b)
{
    return *(int *)a - *(int *)b;
}


/*
 * Sort all the selected icons in the given resource so that
 * they are in a reasonable order for the K validation string
 * commands to work with.  NB: only touches single-icon items;
 * complex ones are left with the same icon numbers.
 */


error * sort_selected_icons (ResourcePtr res)
{
    ItemInfoPtr propsitem = props_current (NULL);
    IconInfoPtr icons = NULL;
    int *numbers = NULL;
    int i, num = 0;
    RectRec damage;

    for (i = 0; i < res->numicons; i++)
    {
        ItemInfoPtr item = res->icons[i].owner;
        if (item && item->selected && numicons[item->type] == 1)
            num++;
    }

    if (num == 0)
        return NULL;

    icons = (IconInfoPtr) malloc (num * sizeof(IconInfoRec));
    if (icons == NULL)
        return error_lookup ("NoMem");
    numbers = (int *) malloc (num * sizeof(int));
    if (numbers == NULL)
    {
        free (icons);
        return error_lookup ("NoMem");
    }

    for (num = i = 0; i < res->numicons; i++)
    {
        ItemInfoPtr item = res->icons[i].owner;
        if (item && item->selected && numicons[item->type] == 1)
        {
            icons[num] = res->icons[i];
            numbers[num] = i;
            num++;
        }
    }

    qsort ((void *) numbers, (size_t) num, sizeof(int), compare_int);
    qsort ((void *) icons, (size_t) num, sizeof(IconInfoRec), compare_icon);

    for (i = 0; i < num; i++)
    {
        res->icons[numbers[i]] = icons[i];
        res->icons[numbers[i]].owner->u.master = numbers[i];
        if (i == 0)
            damage = icons[i].icon.bbox;
        else
            wimp_merge_bboxes (&damage, &damage, &icons[i].icon.bbox);
        if (icons[i].owner == propsitem)
            props_select (res, propsitem);
    }
    
    template_adjust_item_bbox (AddHighlight, &damage, &damage);
    wimp_invalidate (&res->window, &damage);
    document_modified (res->owner, TRUE);

    free (numbers);
    free (icons);
    return NULL;
}
